package com.mlk.sign.service.impl;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.mlk.constant.EngConstant;
import com.mlk.core.constants.Constant;
import com.mlk.core.util.ServerResponse;
import com.mlk.engUser.mapper.EngUserMapper;
import com.mlk.score.mapper.EngInScoreMapper;
import com.mlk.score.po.EngInScore;
import com.mlk.score.strategy.ScoreStrategy;
import com.mlk.sign.mapper.EngSignMapper;
import com.mlk.sign.po.EngSign;
import com.mlk.sign.service.EngSignService;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class EngSignServiceImpl implements EngSignService {

    @Resource
    private EngSignMapper engSignMapper;

    @Resource
    private EngInScoreMapper engInScoreMapper;

    @Resource
    private ScoreStrategy scoreStrategy;

    @Resource
    private EngUserMapper engUserMapper;

    /**
     * 用户签到
     *
     * @param openId
     * @return
     */
    @Override
    @Transactional
    public ServerResponse sign(String openId) {
        // 看看今天是否已经签到了..
        int count = this.engSignMapper.findIsSign(openId);

        if (count > 0) {
            return ServerResponse.fail("今天已经签到了");
        }
        // 没有签到的话,需要新增一条数据.
        count = this.engSignMapper.insert(EngSign.builder().openId(openId).signTime(new Date()).build());
        if (count == 0) {
            return ServerResponse.fail("签到失败");
        }

        // 增加积分信息
        // 确认用户可以增加几个积分
        int score = this.scoreStrategy.signScore(openId);

        // 增加用户积分录入数据
        if (score > 0) {
            // 插入签到积分数据
            count = this.engInScoreMapper.insert(
                    EngInScore
                            .builder()
                            .createTime(new Date())
                            .num(score)
                            .openId(openId)
                            .type(EngConstant.IN_SCORE_SOURCE.SIGN_SCORE)
                            .build());
            if (count == 0) {
                return ServerResponse.fail("签到失败");
            }
            // 给用户账号增加积分
            count = this.engUserMapper.addUserScore(openId, score);

            if (count == 0) {
                return ServerResponse.fail("签到失败");
            }
        }
        return ServerResponse.ok("签到成功");
    }

    /**
     * 获取用户的总积分信息
     *
     * @param openId
     * @return
     */
    @Override
    public ServerResponse getTotalSignScore(String openId) {
        // 实际上就是计算eng_in_score标志中的 type = 1 的总数

        return ServerResponse.ok(this.engInScoreMapper.getTotalSignScore(openId));
    }


    @Override
    public ServerResponse getTotalSignDays(String openId) {
        // 实际上就是计算 eng_sign 表之中 open_id 对应的记录数
        return ServerResponse.ok(this.engSignMapper.getTotalSignDays(openId));
    }

    @Override
    public ServerResponse lastSevenDaysSignInfo(String openId) {
        // 在数据库之中查询openId 最近的7前的数据
        List<Date> info = this.engSignMapper.querylastDaysSignInfo(openId);

        // 将info 映射为string的形式
        List<String> days = info.stream().map(e -> {
            return DateUtil.format(e, Constant.SIMPLE_DATE_FORMAT);
        }).collect(Collectors.toList());

        // 获取最近7天的日期字符串
        List<String> daysStr = Lists.newArrayList();
        for (int i=0;i<7;i++){
            daysStr.add(
                    DateUtil.format(DateUtils.addDays(new Date(),(-1)*i), Constant.SIMPLE_DATE_FORMAT));
        }

        List<Boolean> result = Lists.newArrayList();

        daysStr.forEach(e->{
            if(days.contains(e)){
                result.add(true);
            }else{
                result.add(false);
            }
        });
        Collections.reverse(result);
        return ServerResponse.ok(result);
    }
}
